package cn.byapps.core.dao.impl;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.hibernate.Criteria;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;

import cn.byapps.core.dao.BaseDao;

public abstract class BaseDaoImpl<E> implements BaseDao<E> {

	@Resource
	protected SessionFactory sessionFactory;

	private Class<E> classname;

	@SuppressWarnings("unchecked")
	public BaseDaoImpl() {
		ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass();
		classname = (Class<E>) type.getActualTypeArguments()[0];
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<E> findAll() {
		// 使用Criteria
		return sessionFactory.getCurrentSession().createCriteria(classname).list();

	}

	@SuppressWarnings("unchecked")
	@Override
	public List<E> findAll(Map<String, Object> searchParams) {
		// 使用Criteria
		Criteria criteria = sessionFactory.getCurrentSession().createCriteria(classname);
		for (Map.Entry<String, Object> entry : searchParams.entrySet()) {
			String key = entry.getKey().toString();
			Object value = entry.getValue();
			criteria.add(Restrictions.eq(key, value));
		}
		return criteria.list();

	}

	@Override
	public void add(E entity) {
		sessionFactory.getCurrentSession().saveOrUpdate(entity);
	}

	@SuppressWarnings("unchecked")
	@Override
	public E get(Serializable id) {
		return (E) sessionFactory.getCurrentSession().get(classname, id);

	}

	@SuppressWarnings("unchecked")
	@Override
	public E load(Serializable id) {
		return (E) sessionFactory.getCurrentSession().load(classname, id);

	}

	@Override
	public void update(E entity) {
		sessionFactory.getCurrentSession().update(entity);
	}

	@Override
	public void delete(E entity) {

		sessionFactory.getCurrentSession().delete(entity);
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<E> find(int pos, int rows) {
		// 使用Criteria
		return sessionFactory.getCurrentSession().createCriteria(classname).setMaxResults(rows).setFirstResult(pos)
				.list();

	}

	@SuppressWarnings("unchecked")
	@Override
	public List<E> find(int pos, int rows, Map<String, Object> searchParams) {
		// 使用Criteria
		Criteria criteria = sessionFactory.getCurrentSession().createCriteria(classname);
		for (Map.Entry<String, Object> entry : searchParams.entrySet()) {
			String key = entry.getKey().toString();
			Object value = entry.getValue();
			criteria.add(Restrictions.eq(key, value));
		}
		criteria.setMaxResults(rows);
		criteria.setFirstResult(pos);
		return criteria.list();
	}

	@Override
	public long count() {
		// 使用Criteria
		return (Long) sessionFactory.getCurrentSession().createCriteria(classname).setProjection(Projections.rowCount())
				.uniqueResult();
	}

	@Override
	public long count(Map<String, Object> searchParams) {
		// 使用Criteria
		Criteria criteria = sessionFactory.getCurrentSession().createCriteria(classname);
		for (Map.Entry<String, Object> entry : searchParams.entrySet()) {
			String key = entry.getKey().toString();
			Object value = entry.getValue();
			criteria.add(Restrictions.eq(key, value));
		}
		return (Long) criteria.setProjection(Projections.rowCount()).uniqueResult();
	}

}
